package com.yun.reggie.controller;

import com.yun.reggie.common.R;
import com.yun.reggie.entity.User;
import com.yun.reggie.service.UserService;
import com.yun.reggie.utils.SMSUtils;
import com.yun.reggie.utils.ValidateCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author xiao
 */

@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody User user, HttpSession session){
        //获取手机号
        String phone = user.getPhone();
        if (StringUtils.isEmpty(phone)){
            return R.error("手机号为空！");
        }
        //随机生成4位验证码
        String code = ValidateCodeUtils.generateValidateCode(4).toString();
        log.error("验证码："+code);

        //设置redis存储手机号发送次数的key的规则:手机号+次数。value是count过期时间是24h.
        //手机每天只能发送三次验证码
        Integer count = (Integer) redisTemplate.opsForValue().get(phone+":count");
        if (count == null){
            //今天第一次发验证码
            redisTemplate.opsForValue().set(phone+":count",1,24L,TimeUnit.HOURS);
        }else if(count <= 2){
            //不大于3次，还能发
            redisTemplate.opsForValue().set(phone+":count",count+1,24L,TimeUnit.HOURS);
        }else if (count == 3){
            return R.error("验证码发送次数已用完，请明天再试！");
        }

        //使用阿里云短信服务发送验证码
        //SMSUtils.sendMessage("Reggie","SMS_274470385",phone,code);
        //将验证码缓存入redis中，设置有效期2min
        redisTemplate.opsForValue().set(phone,code,2L, TimeUnit.MINUTES);
        return R.success("验证码发送成功！");
    }

    /**
     * 前端发送的参数，直接接收是接收不到的(前端的原因)
     * 必须使用@RequestBody把json数据封装起来
     * 可以使用前面的数据传输对象dto，继承User，添加一个属性Code
     * @return
     */
    @PostMapping("/login")
    public R<User> login(@RequestBody Map<String,String> user,HttpSession session){
        //log.info(user.toString()); {phone=18207042150, code=1366}
        String phone = user.get("phone");
        String code = user.get("code");
        //从session中获取保存的验证码
        //String codeReal = (String)session.getAttribute(phone);

        //从redis缓存中取验证码
        String codeReal = (String) redisTemplate.opsForValue().get(phone);

        //session域/redis缓存中中没有验证码，说明没有请求验证码/验证码已过期
        if (StringUtils.isEmpty(codeReal)){
            return R.error("请重新获取验证码！");
        }
        if (!codeReal.equals(code)){
            return R.error("验证码错误！");
        }
        //如果验证码正确，则判断是否是新用户，是--自动注册并返回，否则返回老用户信息
        User userReturn = userService.isNewUser(phone);

        //登录成功后，在session域中设置，用于后续请求的放行(过滤器)
        session.setAttribute("user",userReturn.getId());

        //登录成功，删除缓存的验证码
        redisTemplate.delete(phone);

        //不管是不是新用户，只要登录成功了，就返回该用户信息用于显示
        return R.success(userReturn);
    }

    @PostMapping("/loginout")
    public R<String> logout(HttpServletRequest request){
        request.getSession().removeAttribute("user");
        return R.success("退出成功！");
    }
}
